﻿using AutoMapper;
using DFGK.IRepository;
using DFGK.IService;
using DFGK_WMS.Common;
using DFGK_WMS.Model.Dto;
using DFGK_WMS.Model.Dto.YS;
using DFGK_WMS.Model.Enum;
using DFGK_WMS.Model.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;

namespace DFGK.Service
{
    public class InstructService : BaseService, IInstructService
    {
        private readonly IReceivingOrderDetailRepository _receivingOrderDetailRepository;
        private readonly IReceivingBillDetailRepository _receivingBillDetailRepository;
        private readonly IShippingOrderDetailRepository _shippingOrderDetailRepository;
        private readonly IPutawayOrderDetailRepository _putawayOrderDetailRepository;
        private readonly IPickingOrderDetailRepository _pickingOrderDetailRepository;
        private readonly IShippingLockCellRepository _shippingLockCellRepository;
        private readonly IStackingStorageRepository _stackingStorageRepository;
        private readonly WcsHttpClient _wcsHttpClient;
        private readonly IInterfaceLogRepository _interfaceLogRepository;
        private readonly IInventoryDetailRepository _inventoryDetailRepository;
        private readonly IReceivingBillRepository _receivingBillRepository;
        private readonly IPickingOrderRepository _pickingOrderRepository;
        private readonly IPutawayOrderRepository _putawayOrderRepository;
        private readonly IInventoryRepository _inventoryRepository;
        private readonly IInstructRepository _instructRepository;
        private readonly IPalletRepository _palletRepository;
        private readonly ICellRepository _cellRepository;
        private readonly IUnitOfWork _unitOfWork;

        public InstructService(IMapper mapper, IInstructRepository _instructRepository, IReceivingOrderDetailRepository receivingOrderDetailRepository, IShippingLockCellRepository shippingLockCellRepository, IStackingStorageRepository stackingStorageRepository, IPutawayOrderRepository putawayOrderRepository, IPutawayOrderDetailRepository putawayOrderDetailRepository, IReceivingBillRepository _receivingBillRepository, IReceivingBillDetailRepository _receivingBillDetailRepository, IInventoryRepository _inventoryRepository, IInventoryDetailRepository _inventoryDetailRepository, ICellRepository _cellRepository, IUnitOfWork _unitOfWork, IPalletRepository _palletRepository, IShippingOrderDetailRepository _shippingOrderDetailRepository, IPickingOrderRepository _pickingOrderRepository, IPickingOrderDetailRepository _pickingOrderDetailRepository, WcsHttpClient wcsHttpClient, IInterfaceLogRepository interfaceLogRepository) : base(mapper)
        {
            _receivingOrderDetailRepository = receivingOrderDetailRepository;
            _putawayOrderDetailRepository = putawayOrderDetailRepository;
            _shippingLockCellRepository = shippingLockCellRepository;
            _stackingStorageRepository = stackingStorageRepository;
            _putawayOrderRepository = putawayOrderRepository;
            this._receivingBillDetailRepository = _receivingBillDetailRepository;
            this._shippingOrderDetailRepository = _shippingOrderDetailRepository;
            this._pickingOrderDetailRepository = _pickingOrderDetailRepository;
            this._inventoryDetailRepository = _inventoryDetailRepository;
            this._pickingOrderRepository = _pickingOrderRepository;
            this._receivingBillRepository = _receivingBillRepository;
            this._inventoryRepository = _inventoryRepository;
            this._instructRepository = _instructRepository;
            this._palletRepository = _palletRepository;
            this._cellRepository = _cellRepository;
            this._unitOfWork = _unitOfWork;
            _wcsHttpClient = wcsHttpClient;
            _interfaceLogRepository = interfaceLogRepository;
        }

        public List<Instruct> GetInstructList(int InstructType, int Status, string? PalletBarcode, int pageIndex, int pageSize, out int totalCount)
        {
            var instructlist = _instructRepository.GetEntityAlls();
            // 添加条件判断
            if (InstructType != 0)
            {
                instructlist = instructlist.Where(t => t.InstructType == InstructType);
            }

            if (Status != 0)
            {
                instructlist = instructlist.Where(t => t.Status == Status);
            }

            if (!string.IsNullOrEmpty(PalletBarcode))
            {
                instructlist = instructlist.Where(t => t.PalletBarcode.Contains(PalletBarcode));
            }
            var list = _instructRepository.GetEntityAlls(instructlist, pageIndex, pageSize, out totalCount, x => x.CreateDate, false);
            return list.ToList();
        }

        public List<InstructMaterDto> GetInstructMater(long id)
        {
            List<InstructMaterDto> instructMaterDtolist = new List<InstructMaterDto>();
            var tinstructobj = _instructRepository.QueryEntityById(id);
            if (tinstructobj == null)
            {
                return instructMaterDtolist;
            }
            var receiobj = _receivingOrderDetailRepository.QueryEntityById((long)tinstructobj.RelatedOrderId);
            var shipplockobj = _shippingLockCellRepository.QueryIsEntityWhere(x => x.OrderDetailId == tinstructobj.RelatedOrderId);
            InstructMaterDto instructmaterdtoobj = new InstructMaterDto();
            switch (tinstructobj.InstructType)
            {
                case 1:
                    if (receiobj != null)
                    {
                        instructmaterdtoobj.MaterName = receiobj.MaterialName;
                        instructmaterdtoobj.MaterNum = tinstructobj.Qty;
                        instructMaterDtolist.Add(instructmaterdtoobj);
                    }
                    break;
                case 2:
                    if (shipplockobj != null)
                    {
                        instructmaterdtoobj.MaterName = shipplockobj.MaterialName;
                        instructmaterdtoobj.MaterNum = tinstructobj.Qty;
                        instructMaterDtolist.Add(instructmaterdtoobj);
                    }
                    break;
                case 6:
                    if (shipplockobj != null)
                    {
                        //instructmaterdtoobj.MaterName = receiobj.MaterialName;
                        //instructmaterdtoobj.MaterNum = tinstructobj.Qty;
                        //instructMaterDtolist.Add(instructmaterdtoobj);
                        instructmaterdtoobj.MaterName = shipplockobj.MaterialName;
                        instructmaterdtoobj.MaterNum = tinstructobj.Qty;
                        instructMaterDtolist.Add(instructmaterdtoobj);
                    }
                    break;
                case 7:
                    if (receiobj != null)
                    {
                        //instructmaterdtoobj.MaterName = shipplockobj.MaterialName;
                        //instructmaterdtoobj.MaterNum = tinstructobj.Qty;
                        //instructMaterDtolist.Add(instructmaterdtoobj);
                        instructmaterdtoobj.MaterName = receiobj.MaterialName;
                        instructmaterdtoobj.MaterNum = tinstructobj.Qty;
                        instructMaterDtolist.Add(instructmaterdtoobj);
                    }
                    break;
            }
            return instructMaterDtolist;
        }

        public bool CancelInstruct(long id, out string message)
        {
            message = "";
            var instructobj = _instructRepository.QueryEntityById(id);
            if (instructobj == null)
            {
                message = "找不到该指令！";
                return false;
            }
            bool result = false;
            switch (instructobj.InstructType)
            {
                case 1:
                    result = CancelRevingOrder(instructobj, out message);
                    break;
                case 2:
                    result = CancelShippingOrder(instructobj, out message);
                    break;
                case 12:
                    result = CancelPalletShippingOrder(instructobj, out message);
                    break;
                case 3:
                    break;
            }
            return result;
        }

        #region 入库-撤销指令
        private bool CancelRevingOrder(Instruct instructobj, out string message)
        {
            message = "";
            //清楚托盘所在位置
            var pobj = _palletRepository.QueryEntityWhere(x => x.PalletBarcode == instructobj.PalletBarcode);
            if (pobj != null)
            {
                pobj.LocationCode = string.Empty;
                pobj.LocationName = string.Empty;
            }
            //删除指令
            _instructRepository.DelEntity(instructobj);
            if (instructobj.RelatedOrderId == null)
            {
                message = "关联的入库单id有误！";
                return false;
            }
            var reveingor = _receivingOrderDetailRepository.QueryEntityById((long)instructobj.RelatedOrderId);
            if (reveingor == null)
            {
                message = "找不到入库单！";
                return false;
            }
            //删除入库单
            _receivingOrderDetailRepository.DelEntity(reveingor);
            if (instructobj.StackingStorageId == null)
            {
                message = "关联的组垛id有误！";
                return false;
            }
            var stackingstorageobj = _stackingStorageRepository.QueryEntityById((long)instructobj.StackingStorageId);
            if (stackingstorageobj != null)
                //删除组垛信息
                _stackingStorageRepository.DelEntity(stackingstorageobj);

            //上架单
            var putobj = _putawayOrderRepository.QueryEntityWhere(x => x.RelatedOrderDetailId == reveingor.Id && x.Status == 4);
            if (putobj != null)
            {
                //删除上架单
                _putawayOrderRepository.DelEntity(putobj);
                var putdeobj = _putawayOrderDetailRepository.QueryEntityWhere(x => x.PutawayOrderId == putobj.Id);
                if (putdeobj != null)
                    _putawayOrderDetailRepository.DelEntity(putdeobj);
            }
            else
            {
                message = "找不到上架单信息！";
                return false;
            }

            if (reveingor.ReceivingBillId == null)
            {
                message = "关联的收货单id有误！";
                return false;
            }
            //收货单
            var rebvingbillobj = _receivingBillRepository.QueryEntityById((long)reveingor.ReceivingBillId);
            if (rebvingbillobj == null)
            {
                message = "找不到收货单信息！";
                return false;
            }
            //收货单恢复状态和数量          
            rebvingbillobj.BeginDate = null;
            rebvingbillobj.EndDate = null;
            var rebvingbilldetailsobj = _receivingBillDetailRepository.QueryEntityWhere(x => x.BillId == rebvingbillobj.Id);
            if (rebvingbilldetailsobj == null)
            {
                message = "找不到收货单明细信息！";
                return false;
            }
            rebvingbilldetailsobj.ReceivedQty -= instructobj.Qty;
            if(rebvingbilldetailsobj.ReceivedQty == 0)
                rebvingbillobj.Status = 0;
            else
                rebvingbillobj.Status = 1;

            rebvingbilldetailsobj.Status = 0;
            //库存
            var invobj = _inventoryRepository.QueryEntityWhere(x => x.RelatedOrderDetailId == reveingor.Id);
            if (invobj == null)
            {
                message = "找不到库存信息！";
                return false;
            }
            _inventoryRepository.DelEntity(invobj);
            //库存明细
            var indvobj = _inventoryDetailRepository.QueryEntityWhere(x => x.InventoryId == invobj.Id);
            if (indvobj != null)
                _inventoryDetailRepository.DelEntity(indvobj);

            //仓位
            var cellobj = _cellRepository.QueryEntityWhere(x => x.Code == invobj.LocationCode);
            if (cellobj != null)
            {
                cellobj.FullStatus = 0;
                cellobj.IsLock = false;
                cellobj.BusinessType = 0;
                cellobj.Status = 1;
                _cellRepository.UpdEntity(cellobj);
            }
            else
            {
                message = "仓位信息有误！";
                return false;
            }
            if (_unitOfWork.SaveChangesEntity())
            {
                if (!Config.IsDev)
                {
                    ChangeTaskDto changetask = new ChangeTaskDto
                    {
                        TaskCode = putobj.Code,
                        Val = 1
                    };
                    WcsTaskResultDto? wcsresult2 = _wcsHttpClient.ChangeTask(changetask);
                }
                return true;
            }
            return false;
        }
        #endregion

        #region 出库-撤销指令
        private bool CancelShippingOrder(Instruct instructobj, out string message)
        {
            message = "";
            //清楚托盘所在位置
            var pobj = _palletRepository.QueryEntityWhere(x => x.PalletBarcode == instructobj.PalletBarcode);
            if (pobj != null)
            {
                pobj.LocationCode = string.Empty;
                pobj.LocationName = string.Empty;
            }
            //删除指令
            _instructRepository.DelEntity(instructobj);
            if (instructobj.RelatedOrderId == null)
            {
                message = "关联的出库单id有误！";
                return false;
            }
            var sobj = _shippingOrderDetailRepository.QueryEntityById((long)instructobj.RelatedOrderId);
            if (sobj == null)
            {
                message = "找不到出库单！";
                return false;
            }
            else
                sobj.Status = 0;
            //删除出库单
            var sdobj = _shippingLockCellRepository.QueryEntityWhere(x => x.OrderDetailId == sobj.Id);
            if (sdobj == null)
            {
                message = "找不到出库单明细！";
                return false;
            }
            else
                sdobj.Status = 0;
            //下架单
            var pickobj = _pickingOrderRepository.QueryEntityWhere(x => x.RelatedOrderDetailId == sdobj.Id && x.Status == 4);
            if (pickobj != null)
            {
                //删除下架单
                _pickingOrderRepository.DelEntity(pickobj);
                var pickdobj = _pickingOrderDetailRepository.QueryEntityWhere(x => x.OrderId == pickobj.Id);
                if (pickdobj != null)
                    _pickingOrderDetailRepository.DelEntity(pickdobj);
            }
            else
            {
                message = "找不到下架单明细！";
                return false;
            }

            //库存
            var invobj = _inventoryRepository.QueryEntityWhere(x => x.PalletBarcode == sdobj.PalletBarcode && x.Status == 4 && x.IsLock == true);
            if (invobj == null)
            {
                message = "找不到库存信息！";
                return false;
            }
            else
            {
                invobj.IsLock = false;
                invobj.Status = 1;
                _inventoryRepository.UpdEntity(invobj);
            }

            //仓位
            //var cellobj = _cellRepository.QueryEntityWhere(x => x.Code == invobj.LocationCode);
            //if (cellobj != null)
            //{
            //    //cellobj.FullStatus = 0;
            //    cellobj.IsLock = false;
            //    cellobj.BusinessType = 0;
            //    _cellRepository.UpdEntity(cellobj);
            //}
            //else
            //{
            //    message = "仓位信息有误！";
            //    return false;
            //}
            if (_unitOfWork.SaveChangesEntity())
            {
                if (!Config.IsDev)
                {
                    ChangeTaskDto changetask = new ChangeTaskDto
                    {
                        TaskCode = pickobj.Code,
                        Val = 1
                    };
                    WcsTaskResultDto? wcsresult2 = _wcsHttpClient.ChangeTask(changetask);
                    
                }
                return true;
            }
            return false;
        }
        #endregion

        #region 空托盘出库-撤销指令
        private bool CancelPalletShippingOrder(Instruct instructobj, out string message)
        {
            message = "";
            //清楚托盘所在位置
            var pobj = _palletRepository.QueryEntityWhere(x => x.PalletBarcode == instructobj.PalletBarcode);
            if (pobj != null)
            {
                pobj.LocationCode = string.Empty;
                pobj.LocationName = string.Empty;
            }
            //删除指令
            _instructRepository.DelEntity(instructobj);
            if (instructobj.RelatedOrderId == null)
            {
                message = "关联的出库单id有误！";
                return false;
            }
            //下架单
            var pickobj = _pickingOrderRepository.QueryEntityWhere(x => x.PalletBarcode == instructobj.PalletBarcode && x.Status == 4);
            if (pickobj != null)
            {
                //删除下架单
                _pickingOrderRepository.DelEntity(pickobj);
                var pickdobj = _pickingOrderDetailRepository.QueryEntityWhere(x => x.OrderId == pickobj.Id);
                if (pickdobj != null)
                    _pickingOrderDetailRepository.DelEntity(pickdobj);
            }
            else
            {
                message = "找不到下架单明细！";
                return false;
            }

            //库存
            var invobj = _inventoryRepository.QueryEntityWhere(x => x.PalletBarcode == instructobj.PalletBarcode && x.Status == 4 && x.IsLock == true);
            if (invobj == null)
            {
                message = "找不到库存信息！";
                return false;
            }
            else
            {
                invobj.IsLock = false;
                invobj.Status = 1;
                _inventoryRepository.UpdEntity(invobj);
            }

            //仓位
            //var cellobj = _cellRepository.QueryEntityWhere(x => x.Code == invobj.LocationCode);
            //if (cellobj != null)
            //{
            //    //cellobj.FullStatus = 0;
            //    cellobj.IsLock = false;
            //    cellobj.BusinessType = 0;
            //    _cellRepository.UpdEntity(cellobj);
            //}
            //else
            //{
            //    message = "仓位信息有误！";
            //    return false;
            //}
            if (_unitOfWork.SaveChangesEntity())
            {
                if (!Config.IsDev)
                {
                    ChangeTaskDto changetask = new ChangeTaskDto
                    {
                        TaskCode = pickobj.Code,
                        Val = 1
                    };
                    WcsTaskResultDto? wcsresult2 = _wcsHttpClient.ChangeTask(changetask);
                }
                return true;
            }
            return false;
        }
        #endregion
    }
}
